using Godot;
using System;
using Smr.基类;
using Smr.枚举;
using Smr.索引;
using Smr;
using System.Collections.Generic;

public partial class 组件背包 : Control
{
    [Export] private PackedScene 背包道具场景;
    [Export] private GridContainer 道具网格;
    [Export] private TabContainer 选项卡;

    public override void _EnterTree()
    {
        游戏管理.置组件实例("组件背包", this);
    }

    public override void _Ready()
    {
        游戏管理.战斗实例.信号战斗结束 += 置掉落装备;
        创建选项卡选项();
        刷新背包();
        选项卡.TabChanged += current =>
        {
            游戏管理.舞台实例.清空弹窗();
            刷新背包(current - 1);
        };
    }

    public void 刷新背包(long 选项索引 = -1)
    {
        清空背包();
        if (游戏存档.背包.Count > 0)
        {
            for (int i = 0; i < 游戏存档.背包.Count; i++)
            {
                C道具模型 背包道具 = 游戏存档.背包[i];
                if (选项索引 != -1 && (int)背包道具.类型 != 选项卡.CurrentTab - 1)
                {
                    continue;
                }
                组件道具 道具场景 = 背包道具场景.Instantiate<组件道具>();
                道具场景.置道具(背包道具, E道具位置.背包);
                道具网格.AddChild(道具场景);
            }
        }
    }

    public C道具模型 取指定索引背包配置成员(E道具索引 索引, E背包道具使用状态 使用状态 = E背包道具使用状态.不判断)
    {
        for (int i = 0; i < 游戏存档.背包.Count; i++)
        {
            C道具模型 道具 = 游戏存档.背包[i];
            if (道具.索引 == (int)索引)
            {
                switch (使用状态)
                {
                    case E背包道具使用状态.不判断:
                        return 道具;
                    case E背包道具使用状态.未使用:
                        if (!道具.已使用)
                        {
                            return 道具;
                        }
                        break;
                    case E背包道具使用状态.已使用:
                        if (道具.已使用)
                        {
                            return 道具;
                        }
                        break;
                    default:
                        break;
                }
            }
        }
        return null;
    }

    public List<组件道具> 取指定条件的道具组件列表
    (
        E道具索引 索引,
        E道具位置 待添加位置,
        Func<C道具模型, bool> 条件
    )
    {
        List<组件道具> 道具组件数组 = [];
        for (int i = 0; i < 游戏存档.背包.Count; i++)
        {
            C道具模型 道具 = 游戏存档.背包[i];
            if (道具.索引 == (int)索引)
            {
                if (条件(道具))
                {
                    组件道具 道具组件 = 背包道具场景.Instantiate<组件道具>();
                    道具组件.置道具(道具, 待添加位置);
                    道具组件数组.Add(道具组件);
                }
            }
        }
        return 道具组件数组;
    }

    public void 删道具(string UUID, int 删除数量 = 1)
    {
        var 背包道具组 = 道具网格.GetChildren();
        for (int i = 0; i < 背包道具组.Count; i++)
        {
            组件道具 道具场景 = (组件道具)背包道具组[i];
            C道具模型 道具 = 道具场景.取道具();
            if (道具.UUID == UUID)
            {
                if (删除数量 > 0)
                {
                    道具.当前数量 -= 删除数量;
                }
                if (道具.当前数量 <= 0)
                {
                    道具场景.QueueFree();
                    删背包配置成员(UUID);
                    游戏管理.舞台实例.清空弹窗();
                }
                else
                {
                    道具场景.置道具当前数量(道具.当前数量);
                }
                return;
            }
        }
    }

    public void 置道具数量(string UUID, int 数量)
    {
        var 背包道具组 = 道具网格.GetChildren();
        for (int i = 0; i < 背包道具组.Count; i++)
        {
            组件道具 道具场景 = (组件道具)背包道具组[i];
            if (道具场景.取道具().UUID == UUID)
            {
                道具场景.置道具当前数量(数量);
            }
        }
    }

    public long 取选项卡索引()
    {
        return 选项卡.CurrentTab - 1;
    }

    public void 置背包道具(C道具模型 待添加)
    {
        游戏存档.背包.Add(待添加);
        待添加.道具位置 = E道具位置.背包;
        组件道具 道具场景 = 背包道具场景.Instantiate<组件道具>();
        道具场景.置道具(待添加, E道具位置.背包);

        // 判断待添加的道具是否是当前选项页, 如果再添加
        if (选项卡.CurrentTab == 0 || (int)待添加.类型 == 选项卡.CurrentTab - 1)
        {
            道具网格.AddChild(道具场景);
        }
        else
        {
            道具场景.QueueFree();
        }
    }

    public int 取背包道具总数(int 道具索引, E背包道具使用状态 使用状态 = E背包道具使用状态.不判断)
    {
        int 总数 = 0;
        foreach (var 项目 in 游戏存档.背包)
        {
            if (道具索引 == 项目.索引)
            {
                switch (使用状态)
                {
                    case E背包道具使用状态.不判断:
                        总数 += 项目.当前数量;
                        break;
                    case E背包道具使用状态.未使用:
                        if (!项目.已使用)
                        {
                            总数 += 项目.当前数量;
                        }
                        break;
                    case E背包道具使用状态.已使用:
                        if (项目.已使用)
                        {
                            总数 += 项目.当前数量;
                        }
                        break;
                    default:
                        break;
                }
            }
        }
        return 总数;
    }

    public void 置背包配置成员(C道具模型 成员, string UUID = "")
    {
        if (UUID == "")
        {
            游戏存档.背包.Add(成员);
            return;
        }

        for (int i = 0; i < 游戏存档.背包.Count; i++)
        {
            if (游戏存档.背包[i].UUID == UUID)
            {
                游戏存档.背包[i] = 成员;
                return;
            }
        }
    }

    public C道具模型 取背包配置成员(string UUID)
    {
        for (int i = 0; i < 游戏存档.背包.Count; i++)
        {
            if (游戏存档.背包[i].UUID == UUID)
            {
                return 游戏存档.背包[i];
            }

        }
        return null;
    }

    public void 删背包配置成员(string UUID)
    {
        for (int i = 游戏存档.背包.Count - 1; i >= 0; i--)
        {
            if (游戏存档.背包[i].UUID == UUID)
            {
                游戏存档.背包.RemoveAt(i);
                return;
            }
        }
    }

    private void 创建选项卡选项()
    {
        TabBar 选项标签全部 = new()
        {
            Name = "全部"
        };
        选项卡.AddChild(选项标签全部);
        foreach (E道具类型 类型 in Enum.GetValues(typeof(E道具类型)))
        {
            TabBar 选项标签 = new()
            {
                Name = 类型.ToString()
            };
            选项卡.AddChild(选项标签);
        }
    }

    private void 清空背包()
    {
        var 背包道具组 = 道具网格.GetChildren();
        foreach (var 背包道具 in 背包道具组)
        {
            背包道具.QueueFree();
        }
    }

    private void 置掉落装备(Godot.Collections.Array<int> 掉落道具)
    {
        foreach (var 掉落道具索引 in 掉落道具)
        {
            bool 是否添加背包 = true;
            for (int i = 0; i < 游戏存档.背包.Count; i++)
            {
                if (游戏存档.背包[i].索引 == 掉落道具索引)
                {
                    if (!游戏存档.背包[i].可叠加 || 游戏存档.背包[i].当前数量 >= 游戏存档.背包[i].叠加上限)
                    {
                        continue;
                    }
                    游戏存档.背包[i].当前数量 += 1;
                    置道具数量(游戏存档.背包[i].UUID, 游戏存档.背包[i].当前数量);
                    是否添加背包 = false;
                    break;
                }
            }

            if (是否添加背包)
            {
                C道具模型 待添加 = null;
                // 判断是道具
                if (掉落道具索引 >= (int)E道具索引.初始值 && 掉落道具索引 < (int)E装备索引.初始值)
                {
                    待添加 = 道具模型.取模型((E道具索引)掉落道具索引);
                }
                // 判断是装备
                else if (掉落道具索引 >= (int)E装备索引.初始值 && 掉落道具索引 < 50000)
                {
                    C装备模型 待添加装备 = 装备模型.取模型((E装备索引)掉落道具索引);
                    // 添加附加属性
                    for (int i = 0; i < 方法.取随机数.Next(配置.随机野外掉落装备附加属性数量概率[0], 配置.随机野外掉落装备附加属性数量概率[1]); i++)
                    {
                        待添加装备.附加属性.Add(装备属性.取装备属性(待添加装备.称谓要求));
                    }
                    待添加 = 待添加装备;
                }
                if (待添加 != null)
                {
                    置背包道具(待添加);
                }
            }
        }
    }
}
